<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 5.2.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"example.com","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","width_expanded":320,"width_dual_column":240,"display":"post","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"fold":{"enable":false,"height":500},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"Searching...","empty":"We didn't find any results for the search: ${query}","hits_time":"${hits} results found in ${time} ms","hits":"${hits} results found"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta property="og:type" content="article">
<meta property="og:title" content="CSAPP笔记-链接">
<meta property="og:url" content="http://example.com/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/index.html">
<meta property="og:site_name" content="LittleBlackDot">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="http://example.com/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/典型ELF可重定位目标文件.jpg">
<meta property="og:image" content="http://example.com/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/ELF头解析实例.png">
<meta property="article:published_time" content="2024-04-28T14:25:47.000Z">
<meta property="article:modified_time" content="2024-05-26T14:42:06.413Z">
<meta property="article:author" content="LittleBlackDot">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://example.com/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/典型ELF可重定位目标文件.jpg">


<link rel="canonical" href="http://example.com/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"en","comments":true,"permalink":"http://example.com/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/","path":"2024/04/28/CSAPP笔记-链接/","title":"CSAPP笔记-链接"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>CSAPP笔记-链接 | LittleBlackDot</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<link rel="alternate" href="/atom.xml" title="LittleBlackDot" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Toggle navigation bar" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">LittleBlackDot</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="Search" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>Home</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>Archives</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>Search
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="Searching..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          Table of Contents
        </li>
        <li class="sidebar-nav-overview">
          Overview
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%BC%96%E8%AF%91%E5%99%A8%E9%A9%B1%E5%8A%A8%E7%A8%8B%E5%BA%8F"><span class="nav-number">1.</span> <span class="nav-text">编译器驱动程序</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%BA%90%E6%96%87%E4%BB%B6%E5%88%B0%E5%8F%AF%E6%89%A7%E8%A1%8C%E7%9B%AE%E6%A0%87%E6%96%87%E4%BB%B6%E7%9A%84%E8%BF%87%E7%A8%8B"><span class="nav-number">1.1.</span> <span class="nav-text">源文件到可执行目标文件的过程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#linux%E4%B8%AD%E5%8F%AF%E6%89%A7%E8%A1%8C%E7%9B%AE%E6%A0%87%E7%A8%8B%E5%BA%8F%E4%B8%8D%E4%BE%9D%E8%B5%96%E5%8A%A8%E6%80%81%E5%BA%93%E7%9A%84%E8%BF%90%E8%A1%8C%E8%BF%87%E7%A8%8B"><span class="nav-number">1.2.</span> <span class="nav-text">Linux中可执行目标程序（不依赖动态库）的运行过程</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%9B%AE%E6%A0%87%E6%96%87%E4%BB%B6"><span class="nav-number">2.</span> <span class="nav-text">目标文件</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%9D%99%E6%80%81%E9%93%BE%E6%8E%A5"><span class="nav-number">2.1.</span> <span class="nav-text">静态链接</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8F%AF%E9%87%8D%E5%AE%9A%E4%BD%8D%E7%9B%AE%E6%A0%87%E6%96%87%E4%BB%B6"><span class="nav-number">2.2.</span> <span class="nav-text">可重定位目标文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%AC%A6%E5%8F%B7%E8%A7%A3%E6%9E%90"><span class="nav-number">2.3.</span> <span class="nav-text">符号解析</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E7%AC%A6%E5%8F%B7"><span class="nav-number">2.3.1.</span> <span class="nav-text">符号</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E7%AC%A6%E5%8F%B7%E8%A1%A8"><span class="nav-number">2.3.2.</span> <span class="nav-text">符号表</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E7%AC%A6%E5%8F%B7%E8%A7%A3%E6%9E%90-1"><span class="nav-number">2.3.3.</span> <span class="nav-text">符号解析</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E8%A7%A3%E6%9E%90%E5%A4%9A%E9%87%8D%E5%AE%9A%E4%B9%89%E7%9A%84%E5%85%A8%E5%B1%80%E7%AC%A6%E5%8F%B7"><span class="nav-number">2.3.3.1.</span> <span class="nav-text">解析多重定义的全局符号</span></a></li></ol></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%93%BE%E6%8E%A5%E9%9D%99%E6%80%81%E5%BA%93"><span class="nav-number">3.</span> <span class="nav-text">链接静态库</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%87%8D%E5%AE%9A%E4%BD%8D"><span class="nav-number">4.</span> <span class="nav-text">重定位</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8A%A8%E6%80%81%E5%BA%93"><span class="nav-number">5.</span> <span class="nav-text">动态库</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="LittleBlackDot"
      src="/images/head.jpg">
  <p class="site-author-name" itemprop="name">LittleBlackDot</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">11</span>
          <span class="site-state-item-name">posts</span>
        </a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  



<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="en">
    <link itemprop="mainEntityOfPage" href="http://example.com/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.jpg">
      <meta itemprop="name" content="LittleBlackDot">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="LittleBlackDot">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="CSAPP笔记-链接 | LittleBlackDot">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          CSAPP笔记-链接
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">Posted on</span>

      <time title="Created: 2024-04-28 22:25:47" itemprop="dateCreated datePublished" datetime="2024-04-28T22:25:47+08:00">2024-04-28</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">Edited on</span>
      <time title="Modified: 2024-05-26 22:42:06" itemprop="dateModified" datetime="2024-05-26T22:42:06+08:00">2024-05-26</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p> </p>
<a id="more"></a>
<p>csapp有空会读一下，但是总是断断续续的再读，这样看完的东西太容易忘了，梳理记录一下，加深理解，后面回看的时候也方便快速回忆。</p>
<h2 id="编译器驱动程序">编译器驱动程序</h2>
<h3 id="源文件到可执行目标文件的过程">源文件到可执行目标文件的过程</h3>
<ul>
<li><span class="math inline">\(main.c(源文件)\xrightarrow{预处理器(cpp)}main.i(中间文件)\xrightarrow{编译器(cc1)}main.s(汇编文件)\)</span>
<span class="math inline">\(\xrightarrow{汇编器(as)}main.o(可重定位目标文件)\xrightarrow{链接器ld}a.out(可执行目标文件)\)</span></li>
<li>过程中的工具链:
<ul>
<li>预处理器：将对代码做一些预处理操作如：宏定义的文本替换，将头文件的内容复制到include处等</li>
<li>编译器：将.i文件翻译成汇编文件格式为.s，文件内容为可阅读的汇编代码，因为汇编代码与cpu的指令集相关联，所以是不可移植的。</li>
<li>汇编器：将.s文件翻译成机器码文件，不可阅读（可以使用objdump来将.o文件转换为汇编格式）</li>
<li>链接器：将多个.o文件链接合并成一个可执行文件，过程中涉及符号解析，重定位。</li>
</ul></li>
</ul>
<h3 id="linux中可执行目标程序不依赖动态库的运行过程">Linux中可执行目标程序（不依赖动态库）的运行过程</h3>
<ol type="1">
<li>shell中输入运行可执行文件</li>
<li>shell调用操作系统加载器(操作系统API--exec函数族也是这个原理)</li>
<li>加载器将可执行目标文件中的代码和数据复制到内存中</li>
<li>加载器跳转到程序的入口点(_start函数)，执行_start函数.
_start函数是系统目标文件ctrl.o中定义的，对所有C程序都一样</li>
<li>_start函数调用系统启动函数
__libc_start_main(定义在libc.so中),初始化执行环境，然后调用用户层的main函数。</li>
</ol>
<h2 id="目标文件">目标文件</h2>
<p>目标文件有三种：</p>
<ul>
<li>可重定位目标文件：.o文件，包含二进制代码和数据，包含各种节(section)：代码节、数据节等等，每个节都是一个连续的二进制字节序列。</li>
<li>可执行目标文件：应用程序文件，由一系列可重定位目标文件合可共享目标文件(非必须)合并组成</li>
<li>共享目标文件：静态或动态库，可由一系列可重定位目标文件生成</li>
</ul>
<p>目标文件在不同系统上具有不同格式。现代x86-64Linux和Unix采用ELF（Executable
and Linkable Format，执行可链接格式）格式，Windows采用PE（Portable
Executable, 可移植可执行）格式</p>
<h3 id="静态链接">静态链接</h3>
<p>静态链接器（Linux上为ld）以一组可重定位目标文件为输入，生成一个完全链接的可执行目标程序。</p>
<h3 id="可重定位目标文件">可重定位目标文件</h3>
<p><img src="/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/典型ELF可重定位目标文件.jpg" alt="典型的ELF可重定位目标文件结构" style="zoom:30%;"></p>
<p>上图来自CSAPP，描述了一个ELF可重定位目标文件的结构。大致结构就是以一个ELF头开始，后跟许多“节”，最后跟着一个“节头部表”。每个“节”的大小和位置都是由节头部表描述的，每个节都拥有一个固定大小的条目。</p>
<ul>
<li><p><strong>ELF头</strong></p>
<ul>
<li><p>"ELF头"以一个16字节的序列开始，该序列描述了生成该文件的系统的字的大小和字节顺序.</p></li>
<li><p>剩余的部分包含：ELF头的大小、目标文件的类型、机器类型、节头部表的文件偏移、节头部表中条目的大小和数目。</p></li>
<li><p>用readelf解析elf头的例子</p>
<figure>
<img src="/2024/04/28/CSAPP%E7%AC%94%E8%AE%B0-%E9%93%BE%E6%8E%A5/ELF头解析实例.png" alt="readelf解析ELF头">
<figcaption aria-hidden="true">readelf解析ELF头</figcaption>
</figure></li>
</ul></li>
<li><p>节头部表</p>
<p>不同节的位置和大小都是节头部表描述的，其中目标文件中的各个节都在其中有一个对应的条目。</p></li>
<li><p>剩余各个“节”</p>
<ul>
<li>.text节：已编译程序的机器代码</li>
<li>.rodata节：只读数据，例如一些字符串常量、switch语句的跳转表</li>
<li>.data节：已初始化的全局变量和静态C变量。局部变量在运行时保存在栈中
，既不在.data节也不再.bss节。</li>
<li>.bss节：未初始化的全局和静态C变量、被初始化为0的全局或静态变量。在目标文件中不占实际空间，仅仅为一个占位符。在目标文件中，为初始化变量在程序运行前会分配在内存中程序的数据段中，且初始化为0；（注：这里的占位符应该是节头部表中会有.bss节的条目，且符号表中会记录属于.bss段的数据，所以目标文件中可以不存在.bss段实际内容）</li>
<li>.symtab：符号表。存放在程序中定义和引用的函数和全局变量的信息（即除了栈变量的全部变量信息）。每个可重定位目标文件都会存在一份符号表</li>
<li>.rel.text：一个.text节中的列表（描述代码段的重定位信息，用于对.text代码段进行重定位），当链接器把这个目标文件和其他文件组合时需要修改这些位置（重定位）。一般而言任何外部函数和引用全局变量的指令都需要修改。</li>
<li>.rel.data：被模块引用或定义的所有全局变量的重定位信息（描述数据段的重定位信息，用于对.data数据段进行重定位）</li>
<li>.debug：一个调试符号表，其条目是程序中定义的局部变量和类型定义，程序中定义和引用的全局变量，以及原始的C源文件。只有以-g选项编译程序才会有这张表</li>
<li>.line：原始C源文件中的行号和.text节中机器指令之间的映射。也是只有以-g选项编译才会有。</li>
<li>.strtab:一个字符串表，其内容包含.symtab和.debug节中的符号，以及节头部中的节名字。是一个以null结尾的字符串序列。</li>
</ul></li>
</ul>
<h3 id="符号解析">符号解析</h3>
<h4 id="符号">符号</h4>
<p>​
每个可重定位目标文件目标模块m都存在一个符号表(.symtab)，它包含m定义和引用的符号，一般有三种不同的符号：</p>
<ul>
<li>有在m中定义并可以被其他模块引用的的全局符号，对应非静态函数和全局变量</li>
<li>其他模块定义并在m中被引用的全局符号（也叫外部符号），对应其他模块定义的非静态函数和全局变量</li>
<li>只在m中被引用且定义在m中的局部符号，对应static修饰的函数和全局变量。</li>
</ul>
<p>非静态的局部变量的生存期和所在的栈帧相关，不记录在符号表中。</p>
<h4 id="符号表">符号表</h4>
<p>符号表由汇编器根据.s文件中的符号（编译器输出的）构造的，.symtab节中包含ELF符号表。这张表包含一种特殊数据结构的数组。这种数据结构的格式如下(可以尝试在/usr/include/elf.h文件中寻找相关定义)：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">typedef struct</span><br><span class="line">&#123;</span><br><span class="line">  Elf64_Word	st_name;		&#x2F;* Symbol name (string tbl index) *&#x2F;</span><br><span class="line">  unsigned char	st_info;		&#x2F;* Symbol type and binding *&#x2F;</span><br><span class="line">  unsigned char st_other;		&#x2F;* Symbol visibility *&#x2F;</span><br><span class="line">  Elf64_Section	st_shndx;		&#x2F;* Section index *&#x2F;</span><br><span class="line">  Elf64_Addr	st_value;		&#x2F;* Symbol value *&#x2F;</span><br><span class="line">  Elf64_Xword	st_size;		&#x2F;* Symbol size *&#x2F;</span><br><span class="line">&#125; Elf64_Sym;</span><br></pre></td></tr></table></figure>
<p>上诉定义在csapp中给的解析如下,更直观一点：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">typedef struct</span><br><span class="line">&#123;</span><br><span class="line">  int	name;		&#x2F;* Symbol name (string table index) *&#x2F;</span><br><span class="line">  char	type:4,     &#x2F;* function of data *&#x2F;</span><br><span class="line">  	    binding:4;	&#x2F;* local or global *&#x2F;</span><br><span class="line">  char  other;		&#x2F;* Symbol visibility *&#x2F;</span><br><span class="line">  short	section;    &#x2F;* Section index *&#x2F;</span><br><span class="line">  long	value;		&#x2F;* section offset or absolute address *&#x2F;</span><br><span class="line">  int	size;		&#x2F;* object size in byte *&#x2F;</span><br><span class="line">&#125; Elf64_Sym;</span><br></pre></td></tr></table></figure>
<ul>
<li><p>type通常标识符号的类型：数据或函数，符号表中可能包含各个节的条目，以及对应原始源文件的路径名的条目，所以可能有些额外的其他类型</p></li>
<li><p>binding表示符号是本地的还是全局的。</p></li>
<li><p>name是字符串表中偏移，以此确定符号的名字（保存在字符串表中）。</p></li>
<li><p>value是符号在定义其的节中的偏移，对于可执行目文件是一个绝对运行时地址。</p></li>
<li><p>size是符号的大小</p></li>
<li><p>section表示符号定义所在的节，其值实际是节头表的索引值。存在三个特殊的伪节（UNDEF、COMMON、ABS），在节头表中没有具体的对应条目，但会成为此section字段的值。</p>
<ul>
<li>ABS代表不该被重定位的符号</li>
<li>UNDEF代表未定义的符号</li>
<li>COMMON表示还未被分配位置的未初始化的数据目标。</li>
</ul></li>
<li><p>COMMON节的符号和.bss节的符号区别很小现代的GCC版本根据以下规则来区分：</p>
<ul>
<li>COMMON：未初始化的全局变量</li>
<li>.bss: 未初始化的静态变量，以及初始化为0的全局或静态变量</li>
</ul>
<p>上述规则的依据主要是根据：编译器处理符号时，将可以确定定义的强符号归结.bss节中，将不确定定义的弱符号归结为COMMON节中。</p></li>
</ul>
<h4 id="符号解析-1">符号解析</h4>
<p>​
链接器解析符号引用的方法是：将每个引用与输入给它的可重定位目标文件里的符号表中的一个确定的符号定义关联起来。</p>
<p>​
对于那些定义和被引用在同一个目标文件的符号，符号解析是很简单的，静态局部变量会有本地链接器符号，编译器需要确保他们拥有唯一的名字。</p>
<p>​
对于全局符号，需要额外多考虑一些。当编译器遇到一个不是在当前模块中定义的符号，会假设这个符号是定义在其他模块，生成一个符号表条目。如果链接器在其他任何输入模块的符号表中都没有找到对应的符号定义，链接就会失败。</p>
<h5 id="解析多重定义的全局符号">解析多重定义的全局符号</h5>
<p>​
对全局符号的解析是存在一些麻烦的，因为多个目标文件中可能会定义多个同名的符号。</p>
<p>​
链接器处理一系列目标文件时，若出现这种场景，不会立刻结束链接，输出错误，而是采用一些默认的规则来处理以试图选出一个定义采用而抛弃其他定义。这个默认的规则引申出强、弱符号这两个概念:</p>
<ul>
<li>强符号：函数和已初始化的变量对应的符号。</li>
<li>弱符号：未初始化的全局变量对应的符号。</li>
</ul>
<p>​ 根据强弱规则的定义，Linux链接器使用如下规则处理多重定义的符号：</p>
<ol type="1">
<li>不允许存在多个同名的强符号</li>
<li>如果存在一个强符号和多个若符号则采用强符号，作为符号</li>
<li>如果只存在多个弱符号，则从中随机的选一个，作为符号</li>
</ol>
<h2 id="链接静态库">链接静态库</h2>
<h2 id="重定位">重定位</h2>
<h2 id="动态库">动态库</h2>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="followme">
  <span>Welcome to my other publishing channels</span>

  <div class="social-list">

      <div class="social-item">
          <a target="_blank" class="social-link" href="/atom.xml">
            <span class="icon">
              <i class="fa fa-rss"></i>
            </span>

            <span class="label">RSS</span>
          </a>
      </div>
  </div>
</div>


        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2024/04/19/CMake%E7%AC%94%E8%AE%B0/" rel="prev" title="CMake笔记">
                  <i class="fa fa-angle-left"></i> CMake笔记
                </a>
            </div>
            <div class="post-nav-item">
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 
    <span itemprop="copyrightYear">2024</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">LittleBlackDot</span>
  </div>
  <div class="powered-by">Powered by <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/" rel="noopener" target="_blank">NexT.Gemini</a>
  </div>

<div>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<span id="busuanzi_container_site_pv" style='display:none'>
    本站总访问量 <span id="busuanzi_value_site_pv"></span> 次
    <span class="post-meta-divider">|</span>
</span>
<span id="busuanzi_container_site_uv" style='display:none'>
    有<span id="busuanzi_value_site_uv"></span>人看过我的博客
</span>
</div>

    </div>
  </footer>

  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>
  <div class="sidebar-dimmer"></div>
  <div class="back-to-top" role="button" aria-label="Back to top">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/sidebar.js"></script><script src="/js/next-boot.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>







  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>



</body>
</html>
